﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Linq.Expressions;
using System.Collections;

namespace OF.Controls
{
    /// <summary>
    /// 文件名称：MVC控件，单选列表和复选列表
    /// </summary>
    public static class MVCControl
    {
        /// <summary>
        /// 单选列表控件
        /// </summary>
        /// <param name="help"></param>
        /// <param name="name">控件名称</param>
        /// <param name="source">控件绑定的数据源</param>
        /// <returns></returns>
        public static MvcHtmlString RadioList(this HtmlHelper help, 
            string name, 
            IEnumerable<SelectListItem> source)
        {
            if (name == null || string.IsNullOrEmpty(name))
                throw new ArgumentException("值不能为 null 或为空", "name");
            string radioName = name;
            if (source != null && source.Any())
            {
                var builder = new StringBuilder();
                int i = 1;
                foreach (var item in source)
                {
                    builder.AppendFormat("<label><input id='Radio_{0}{1}' {4} type='radio' name='{0}' value='{2}' />{3}</label>", radioName, i, item.Value, item.Text, item.Selected ? "checked='checked'" : "");
                    i++;
                }
                return MvcHtmlString.Create(builder.ToString());
            }
            return MvcHtmlString.Create(string.Empty);
        }
        /// <summary>
        /// 单选列表控件
        /// </summary>
        /// <param name="help"></param>
        /// <param name="name">控件名称</param>
        /// <param name="source">控件绑定的数据源</param>
        /// <param name="selecedValue">控件选中的项的值</param>
        /// <returns></returns>
        public static MvcHtmlString RadioList(this HtmlHelper help, string name, 
            IEnumerable<SelectListItem> source, 
            object selecedValue)
        {
            if (name == null || string.IsNullOrEmpty(name))
                throw new ArgumentException("值不能为 null 或为空", "name");
            string radioName = name;
            if (source != null && source.Any())
            {
                var builder = new StringBuilder();
                int i = 1;
                foreach (var item in source)
                {
                    builder.AppendFormat("<label><input id='Radio_{0}{1}' {4} type='radio' name='{0}' value='{2}' />{3}</label>", radioName, i, item.Value, item.Text, (selecedValue != null && selecedValue.ToString() == item.Value ? "checked='checked'" : ""));
                    i++;
                }
                return MvcHtmlString.Create(builder.ToString());
            }
            return MvcHtmlString.Create(string.Empty);
        }
        /// <summary>
        /// 单选列表控件
        /// </summary>
        /// <typeparam name="TModel">通常是指强类型分布视图的强类型</typeparam>
        /// <typeparam name="TProperty">通常是指本控件所对应的类型的属性类型</typeparam>
        /// <param name="help"></param>
        /// <param name="expression">通过类型返回类型属性的表达式</param>
        /// <param name="source">控件绑定的数据源</param>
        /// <returns></returns>
        public static MvcHtmlString RadioListFor<TModel, TProperty>(this HtmlHelper<TModel> help, 
            Expression<Func<TModel, TProperty>> expression, 
            IEnumerable<SelectListItem> source)
        {
            string exprestr = expression.ToString();
            string radioName = exprestr.Substring(exprestr.IndexOf('.') + 1);
            if (source != null && source.Any())
            {
                var builder = new StringBuilder();
                var i = 1;
                foreach (var item in source)
                {
                    builder.AppendFormat("<label><input id='Radio_{0}{1}' {4} type='radio' name='{0}' value='{2}' />{3}</label>", radioName, i, item.Value, item.Text, item.Selected ? "checked='checked'" : "");
                    i++;
                }
                return MvcHtmlString.Create(builder.ToString());
            }
            return MvcHtmlString.Create(string.Empty);
        }
        /// <summary>
        /// 单选列表控件
        /// </summary>
        /// <typeparam name="TModel">通常是指强类型分布视图的强类型</typeparam>
        /// <typeparam name="TProperty">通常是指本控件所对应的类型的属性类型</typeparam>
        /// <param name="help"></param>
        /// <param name="expression">通过类型返回类型属性的表达式</param>
        /// <param name="source">控件绑定的数据源</param>
        /// <param name="selecedValue">控件选中的项的值</param>
        /// <returns></returns>
        public static MvcHtmlString RadioListFor<TModel, TProperty>(this HtmlHelper<TModel> help, 
            Expression<Func<TModel, TProperty>> expression, 
            IEnumerable<SelectListItem> source, 
            object selecedValue)
        {
            string exprestr = expression.ToString();
            string radioName = exprestr.Substring(exprestr.IndexOf('.') + 1);
            if (source != null && source.Any())
            {
                var builder = new StringBuilder();
                var i = 1;
                foreach (var item in source)
                {
                    builder.AppendFormat("<label><input id='Radio_{0}{1}' {4} type='radio' name='{0}' value='{2}' />{3}</label>", radioName, i, item.Value, item.Text, (selecedValue != null && selecedValue.ToString() == item.Value ? "checked='checked'" : ""));
                    i++;
                }
                return MvcHtmlString.Create(builder.ToString());
            }
            return MvcHtmlString.Create(string.Empty);
        }

        /// <summary>
        /// 复选列表控件
        /// </summary>
        /// <param name="help"></param>
        /// <param name="name">控件名称</param>
        /// <param name="source">控件绑定的数据源</param>
        /// <returns></returns>
        public static MvcHtmlString CheckBoxList(this HtmlHelper help, 
            string name, 
            IEnumerable<SelectListItem> source)
        {
            if (name == null || string.IsNullOrEmpty(name))
                throw new ArgumentException("值不能为 null 或为空", "name");
            string chkName = name;
            if (source != null && source.Any())
            {
                var builder = new StringBuilder();
                var i = 1;
                foreach (var item in source)
                {
                    builder.AppendFormat("<label><input id='CheckBox_{0}{1}' {4} type='checkbox' name='{0}' value='{2}' />{3}</label>", chkName, i, item.Value, item.Text, item.Selected ? "checked='checked'" : "");
                    i++;
                }
                return MvcHtmlString.Create(builder.ToString());
            }
            return MvcHtmlString.Create(string.Empty);
        }
        /// <summary>
        /// 复选列表控件
        /// </summary>
        /// <param name="help"></param>
        /// <param name="name">控件名称</param>
        /// <param name="source">控件绑定的数据源</param>
        /// <param name="selectedValues">控件选中的项的值列表</param>
        /// <returns></returns>
        public static MvcHtmlString CheckBoxList(this HtmlHelper help, 
            string name, 
            IEnumerable<SelectListItem> source, 
            IEnumerable selectedValues)
        {
            if (name == null || string.IsNullOrEmpty(name))
                throw new ArgumentException("值不能为 null 或为空", "name");
            string chkName = name;
            if (source != null && source.Any())
            {
                var builder = new StringBuilder();
                var i = 1;
                foreach (var item in source)
                {
                    builder.AppendFormat("<label><input id='CheckBox_{0}{1}' {4} type='checkbox' name='{0}' value='{2}' />{3}</label>", chkName, i, item.Value, item.Text, (selectedValues != null && selectedValues.Contains(item.Value) ? "checked='checked'" : ""));
                    i++;
                }
                return MvcHtmlString.Create(builder.ToString());
            }
            return MvcHtmlString.Create(string.Empty);
        }
        /// <summary>
        /// 复选列表控件
        /// </summary>
        /// <typeparam name="TModel">通常是指强类型分布视图的强类型</typeparam>
        /// <typeparam name="TProperty">通常是指本控件所对应的类型的属性类型</typeparam>
        /// <param name="help"></param>
        /// <param name="expression">通过类型返回类型属性的表达式</param>
        /// <param name="source">控件绑定的数据源</param>
        /// <returns></returns>
        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> help, 
            Expression<Func<TModel, TProperty>> expression, 
            IEnumerable<SelectListItem> source)
        {
            string exprestr = expression.ToString();
            string chkName = exprestr.Substring(exprestr.IndexOf('.') + 1);
            if (source != null && source.Any())
            {
                var builder = new StringBuilder();
                var i = 1;
                foreach (var item in source)
                {
                    builder.AppendFormat("<label><input id='CheckBox_{0}{1}' {4} type='checkbox' name='{0}' value='{2}' />{3}</label>", chkName, i, item.Value, item.Text, item.Selected ? "checked='checked'" : "");
                    i++;
                }
                return MvcHtmlString.Create(builder.ToString());
            }
            return MvcHtmlString.Create(string.Empty);
        }
        /// <summary>
        /// 复选列表控件
        /// </summary>
        /// <typeparam name="TModel">通常是指强类型分布视图的强类型</typeparam>
        /// <typeparam name="TProperty">通常是指本控件所对应的类型的属性类型</typeparam>
        /// <param name="help"></param>
        /// <param name="expression">通过类型返回类型属性的表达式</param>
        /// <param name="source">控件绑定的数据源</param>
        /// <param name="selectedValues">控件选中的项的值列表</param>
        /// <returns></returns>
        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> help, 
            Expression<Func<TModel, TProperty>> expression, 
            IEnumerable<SelectListItem> source, 
            IEnumerable selectedValues)
        {
            string exprestr = expression.ToString();
            string chkName = exprestr.Substring(exprestr.IndexOf('.') + 1);
            if (source != null && source.Any())
            {
                var builder = new StringBuilder();
                var i = 1;
                foreach (var item in source)
                {
                    builder.AppendFormat("<label><input id='CheckBox_{0}{1}' {4} type='checkbox' name='{0}' value='{2}' />{3}</label>", chkName, i, item.Value, item.Text, (selectedValues != null && selectedValues.Contains(item.Value) ? "checked='checked'" : ""));
                    i++;
                }
                return MvcHtmlString.Create(builder.ToString());
            }
            return MvcHtmlString.Create(string.Empty);
        }

        static bool Contains(this IEnumerable enumerable, object obj)
        {
            if (enumerable == null || obj == null)
                return false;
            var enumerator = enumerable.GetEnumerator();
            while (enumerator.MoveNext())
            {
                if (enumerator.Current != null && enumerator.Current.ToString() == obj.ToString())
                    return true;
            }
            return false;
        }
    }
}
